/*
 * Copyright (c) 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessProtectedResource;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.plus.Plus;
import com.google.api.services.plus.model.*;

import java.io.IOException;

/**
 * @author Yaniv Inbar
 * @author Tony Aiuto
 * @author Will Norris
 * @author Jenny Murphy
 */
public class Sample {

  private static Plus plus;
  private static Plus unauthenticatedPlus;

  public static void main(String[] args) throws IOException {
    Util.enableLogging();

    try {
      setupTransport();
      
      getProfile();
      listActivities();
      getActivity();
    } catch (HttpResponseException e) {
      System.err.println(e.getResponse().parseAsString());
      throw e;
    }
  }

  /**
   * Setup the transport for our API calls.
   */
  private static void setupTransport() throws IOException {
    // Set up an unauthenticated client for requests that do not require authentication
    unauthenticatedPlus = new Plus(new NetHttpTransport(), new GsonFactory());
    unauthenticatedPlus.setKey(Auth.GOOGLE_API_KEY);

    Auth.authorize();
    
    // Set up the request initializer in such a way that it can refresh access tokens
    // for us when they expire
    GoogleAccessProtectedResource requestInitializer = new GoogleAccessProtectedResource(
            Auth.getAccessToken(),
            new NetHttpTransport(),
            new GsonFactory(),
            Auth.CLIENT_ID,
            Auth.CLIENT_SECRET,
            Auth.getRefreshToken());

    plus = new Plus(new NetHttpTransport(), requestInitializer, new GsonFactory());
  }

  /**
   * List the public activities for the authenticated user
   *
   * @throws IOException if unable to call API
   */
  private static void listActivities() throws IOException {
    header("Listing My Activities");

    // Fetch the first page of activities
    ActivityFeed feed = plus.activities().list("me", "public").execute();

    while (feed.getItems() != null) {
      System.out.println();
      System.out.println("~~~~~~~~~~~~~~~~~~ New page of activities ~~~~~~~~~~~~~~~~~~");
      System.out.println();

      for (Activity activity : feed.getItems()) {

        show(activity);
        System.out.println();
        System.out.println("------------------------------------------------------");
        System.out.println();
      }
      
      // Fetch the next page
      Plus.Activities.List list = plus.activities().list("me", "public");
      list.setPageToken(feed.getNextPageToken());
      feed = list.execute();
    }
  }

  /**
   * Get the most recent activity for the authenticated user.
   *
   * @throws IOException if unable to call API
   */
  private static void getActivity() throws IOException {
    // A known public activity ID
    String activityId = "z12gtjhq3qn2xxl2o224exwiqruvtda0i";

    if(activityId != null) {
      // Now that we have an ID we can fetch the activity with that ID
      // We do not need to be authenticated to do this
      header("Get an explicit public activity by ID");
      Activity activity = unauthenticatedPlus.activities().get(activityId).execute();
      show(activity);
    }
  }


  /**
   * Get the profile for the authenticated user.
   *
   * @throws IOException if unable to call API
   */
  private static void getProfile() throws IOException {
    header("Get my Google+ profile");
    Person profile = plus.people().get("me").execute();
    show(profile);
  }

  /**
   * Print the specified person on the command line.
   *
   * @param person the person to show
   */
  private static void show(Person person) {
    System.out.println("id: " + person.getId());
    System.out.println("name: " + person.getDisplayName());
    System.out.println("image url: " + person.getImage().getUrl());
    System.out.println("profile url: " + person.getUrl());
  }

  /**
   * Print the specified activity on the command line.
   *
   * @param activity the activity to show
   */
  private static void show(Activity activity) {
    System.out.println("id: " + activity.getId());
    System.out.println("url: " + activity.getUrl());
    System.out.println("content: " + activity.getPlusObject().getContent());
  }

  private static void header(String name) {
    System.out.println();
    System.out.println("============== " + name + " ==============");
    System.out.println();
  }
}
